home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips / loadfont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-05  |  6.5 KB  |  263 lines

  1. /*
  2.  *   Here's the code to load a PK file into memory.
  3.  *   Individual bitmaps won't be unpacked until they prove to be needed.
  4.  */
  5. #include "structures.h" /* The copyright notice in that file is included too! */
  6. /*
  7.  *   These are the external routines we use.
  8.  */
  9. extern void makefont() ;
  10. extern void error() ;
  11. extern integer scalewidth() ;
  12. extern void tfmload() ;
  13. extern FILE *search() ;
  14. /*
  15.  *   These are the external variables we use.
  16.  */
  17. #ifdef DEBUG
  18. extern integer debug_flag;
  19. #endif  /* DEBUG */
  20. extern long bytesleft ;
  21. extern quarterword *raster ;
  22. extern int actualdpi ;
  23. extern real alpha ;
  24. extern char *pkpath ;
  25. char errbuf[200] ;
  26. /*
  27.  *   We use malloc here.
  28.  */
  29. char *malloc() ;
  30.  
  31. /*
  32.  *   Now we have some routines to get stuff from the PK file.
  33.  *   Subroutine pkbyte returns the next byte.
  34.  */
  35.  
  36. static FILE *pkfile ;
  37. static char name[50] ;
  38. void
  39. badpk(s)
  40.    char *s ;
  41. {
  42.    (void)sprintf(errbuf,"! Bad PK file %s: %s",name,s) ;
  43.    error(errbuf);
  44. }
  45.  
  46. shalfword
  47. pkbyte()
  48. {
  49.    register shalfword i ;
  50.  
  51.    if ((i=getc(pkfile))==EOF)
  52.       badpk("unexpected eof") ;
  53.    return(i) ;
  54. }
  55.  
  56. integer
  57. pkquad()
  58. {
  59.    register integer i ;
  60.  
  61.    i = pkbyte() ;
  62.    if (i > 127)
  63.       i -= 256 ;
  64.    i = i * 256 + pkbyte() ;
  65.    i = i * 256 + pkbyte() ;
  66.    i = i * 256 + pkbyte() ;
  67.    return(i) ;
  68. }
  69.  
  70. integer
  71. pktrio()
  72. {
  73.    register integer i ;
  74.  
  75.    i = pkbyte() ;
  76.    i = i * 256 + pkbyte() ;
  77.    i = i * 256 + pkbyte() ;
  78.    return(i) ;
  79. }
  80.  
  81.  
  82. /*
  83.  *   pkopen opens the pk file.  This is system dependent.
  84.  */
  85. static int dontmakefont = 0 ; /* if makefont fails once we won't try again */
  86.  
  87. Boolean
  88. pkopen(fd)
  89.         register fontdesctype *fd ;
  90. {
  91.    register char *d, *n ;
  92.    register int del ;
  93.    register halfword givendpi ;
  94.  
  95.    d = fd->area ;
  96.    n = fd->name ;
  97.    if (*d==0)
  98.       d = pkpath ;
  99.    givendpi = fd->dpi ;
  100.    for (del=0; (real)del/(real)givendpi<=0.01; del = del>0? -del: -del+1 ) {
  101.       (void)sprintf(name, "%s.%dpk", n, givendpi+del) ;
  102.       if (pkfile=search(d, name))
  103.          return(1) ;
  104.    }
  105.    (void)sprintf(name, "%s.%dpk", n, givendpi) ;
  106.    if (d == pkpath && dontmakefont == 0) {
  107.       makefont(n, (int)givendpi, DPI) ;
  108.       if (pkfile = search(d, name))
  109.          return(1) ;
  110.       dontmakefont = 1 ;
  111.    }
  112.    (void)sprintf(errbuf,
  113.       "Font %s%s not found, characters will be left blank.",
  114.       fd->area, name) ;
  115.    error(errbuf) ;
  116.    return(0) ;
  117. }
  118.  
  119. /*
  120.  *   Now our loadfont routine.
  121.  */
  122. void
  123. loadfont(curfnt)
  124.         register fontdesctype *curfnt ;
  125. {
  126.    register shalfword i ;
  127.    register shalfword cmd ;
  128.    register integer k ;
  129.    register integer length ;
  130.    register shalfword cc ;
  131.    register integer scaledsize = curfnt->scaledsize ;
  132.    register quarterword *tempr ;
  133.    register chardesctype *cd ;
  134.  
  135. /*
  136.  *   We clear out some pointers:
  137.  */
  138.    for (i=0; i<256; i++) {
  139.       curfnt->chardesc[i].TFMwidth = 0 ;
  140.       curfnt->chardesc[i].packptr = NULL ;
  141.       curfnt->chardesc[i].pixelwidth = 0 ;
  142.       curfnt->chardesc[i].flags = 0 ;
  143.    }
  144.    if (!pkopen(curfnt)) {
  145.       tfmload(curfnt) ;
  146.       return ;
  147.    }
  148. #ifdef DEBUG
  149.    if (dd(D_FONTS))
  150.       (void)fprintf(stderr,"Loading virtual font %s at %.1fpt\n",
  151.          name, (real)scaledsize/(alpha*0x100000)) ;
  152. #endif /* DEBUG */
  153.    if (pkbyte()!=247)
  154.       badpk("expected pre") ;
  155.    if (pkbyte()!=89)
  156.       badpk("wrong id byte") ;
  157.    for(i=pkbyte(); i>0; i--)
  158.       (void)pkbyte() ;
  159.    k = (integer)(alpha * (real)pkquad()) ;
  160.    if (k > curfnt->designsize + 2 || k < curfnt->designsize - 2) {
  161.       (void)sprintf(errbuf,"Design size mismatch in font %s", name) ;
  162.       error(errbuf) ;
  163.    }
  164.    k = pkquad() ;
  165.    if (k && curfnt->checksum)
  166.       if (k!=curfnt->checksum) {
  167.          (void)sprintf(errbuf,"Checksum mismatch in font %s", name) ;
  168.          error(errbuf) ;
  169.        }
  170.    k = pkquad() ; /* assume that hppp is correct in the PK file */
  171.    k = pkquad() ; /* assume that vppp is correct in the PK file */
  172. /*
  173.  *   Now we get down to the serious business of reading character definitions.
  174.  */
  175.    while ((cmd=pkbyte())!=245) {
  176.       if (cmd < 240) {
  177.          switch (cmd & 7) {
  178. case 0: case 1: case 2: case 3:
  179.             length = (cmd & 7) * 256 + pkbyte() - 3 ;
  180.             cc = pkbyte() ;
  181.             cd = curfnt->chardesc+cc ;
  182.             cd->TFMwidth = scalewidth(pktrio(), scaledsize) ;
  183.             cd->pixelwidth = pkbyte() ;
  184.             break ;
  185. case 4:
  186.             length = pkbyte() * 256 ;
  187.             length = length + pkbyte() - 4 ;
  188.             cc = pkbyte() ;
  189.             cd = curfnt->chardesc+cc ;
  190.             cd->TFMwidth = scalewidth(pktrio(), scaledsize) ;
  191.             i = pkbyte() ;
  192.             cd->pixelwidth = i * 256 + pkbyte() ;
  193.             break ;
  194. case 5: case 6:
  195.             badpk("! character too big") ;
  196. case 7:
  197.             length = pkquad() - 11 ;
  198.             cc = pkquad() ;
  199.             if (cc<0 || cc>255) badpk("character code out of range") ;
  200.             cd = curfnt->chardesc + cc ;
  201.             cd->TFMwidth = scalewidth(pkquad(), scaledsize) ;
  202.             cd->pixelwidth = (pkquad() + 32768) >> 16 ;
  203.             k = pkquad() ;
  204.          }
  205.          if (length <= 0)
  206.             badpk("packet length too small") ;
  207.          if (bytesleft < length) {
  208. #ifdef DEBUG
  209.              if (dd(D_FONTS))
  210.                 (void)fprintf(stderr,
  211.                    "Allocating new raster memory (%d req, %d left)\n",
  212.                                 length, bytesleft) ;
  213. #endif /* DEBUG */
  214.              if (length > MINCHUNK) {
  215.                 tempr = (quarterword *)malloc((unsigned int)length) ;
  216.                 bytesleft = 0 ;
  217.              } else {
  218.                 raster = (quarterword *)malloc(RASTERCHUNK) ;
  219.                 tempr = raster ;
  220.                 bytesleft = RASTERCHUNK - length ;
  221.                 raster += length ;
  222.             }
  223.             if (tempr == NULL)
  224.                error("! out of memory while allocating raster") ;
  225.          } else {
  226.             tempr = raster ;
  227.             bytesleft -= length ;
  228.             raster += length ;
  229.          }
  230.          cd->packptr = tempr ;
  231.          *tempr++ = cmd ;
  232.          for (length--; length>0; length--)
  233.             *tempr++ = pkbyte() ;
  234.       } else {
  235.          k = 0 ;
  236.          switch (cmd) {
  237. case 243:
  238.             k = pkbyte() ;
  239.             if (k > 127)
  240.                k -= 256 ;
  241. case 242:
  242.             k = k * 256 + pkbyte() ;
  243. case 241:
  244.             k = k * 256 + pkbyte() ;
  245. case 240:
  246.             k = k * 256 + pkbyte() ;
  247.             while (k-- > 0)
  248.                i = pkbyte() ;
  249.             break ;
  250. case 244:
  251.             k = pkquad() ;
  252.             break ;
  253. case 246:
  254.             break ;
  255. default:
  256.             badpk("! unexpected command") ;
  257.          }
  258.       }
  259.    }
  260.    (void)fclose(pkfile) ;
  261.    curfnt->loaded = 1 ;
  262. }
  263.